#include <iostream>

using namespace std;

// The Day of Every month
int emonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Totla Days of the month before
int smonth[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 303, 334, 365};

class CDate {
    private:
        int year, month, day;
        bool leap;
        int OneYearDay;

    public:
        CDate(int y=2014, int m=04, int d=29) {
            year    = y;
            month   = m;
            day     = d;
        }

        ~CDate() {
			cout << " I'm being destroyed..." << endl;
		};

		void IsLeap();
        void AddOneDay();
        void SubOneDay();
        void AddDays(int d);
        void SubDays(int d);
        void SubDays_less_than_year(int d);
        void SubDays_more_than_year(int d);

        void print();
		friend ostream & operator << (ostream & stream, const CDate & obj);
};

void CDate::IsLeap() {
	if(year%400==0 || year%4==0 && year%100!=0) {
        emonth[2] = 29;
		leap = true;
		OneYearDay = 366;
	} else {
        emonth[2] = 28;
		leap = false;
		OneYearDay = 365;
	}
}

void CDate::AddOneDay() {
	IsLeap();
    day ++;
    if(day > emonth[month]) {
        day %= emonth[month];
        month ++;

        if(month > 12) {
            month %= 12;
            year++;
        }
    }
}

void CDate::AddDays(int d) {
	bool MoreThanYear = false;
    while(d > 0) {
        AddOneDay();
		d --;
		if(month==12 && day==31) {
			MoreThanYear = true;
			break;
		}
	}

	// More Than This Year && d more than OneYearDay
	if (MoreThanYear)
		while(d > OneYearDay) {
			d -= OneYearDay;
			year += 1;
			IsLeap();
		}
	
	// More Than  This Year && d less than OneYearDay
	if(d > 0)
		for(int i=0; i<d; i++)
			AddOneDay();
}

void CDate::SubOneDay() {
	IsLeap();
	day --;
	if( day <=0 ) {
		month -= 1;
		if(month <= 0) {
			year -= 1;
			month = 12;
			day = 31;
		} else {
			day = emonth[month];
		}
	}
}

void CDate::SubDays_less_than_year(int d) {
    for(int i=0; i<d; i++) {
		SubOneDay();
	}
}

void CDate::SubDays_more_than_year(int d) {
	d -= (smonth[month-1]+day); // the year before ,12.31
	year 	= year - 1;
	month 	= 12;
	day 	= 31;

	IsLeap();
	while(d >= OneYearDay) {
		d 		-= OneYearDay;
		year 	-= 1;
		IsLeap();
	}

	SubDays_less_than_year(d);
}

void CDate::SubDays(int d) {
	IsLeap(); // modify : OneYearDay
	if(d < OneYearDay) {
		SubDays_less_than_year(d);
	} else {
		SubDays_more_than_year(d);
	}
}

/*void CDate::AddDays(int d) {
			
}*/

void CDate::print() {
    cout << year << "年" << month << "月" << day << "日" << endl;
}

ostream & operator << (ostream & stream, const CDate & obj) {
	stream << obj.year << "-" << obj.month << "-" << obj.day;
	return stream;
}

int main(int argc, char * argv[]) {
    CDate dl(2014, 4, 30);

	cout << "Now: " << dl << endl;;

	cout << "Add One Day: ";
    dl.AddOneDay();
    cout << dl << endl;

	int days = 300000000;
	cout << "Add " << days << " Day(s): "; 
    dl.AddDays(days);
    cout << dl << endl;

	days = 300000000;
	cout << "Sub " << days << " Day(s): ";
    dl.SubDays(days);
    cout << dl << endl;

    return 0;
}
